<?php

namespace api\modules\mini\forms\patient;

use common\helpers\DateHelper;
use common\models\base\TreatmentProject;
use common\models\patient\Patient;
use common\models\patient\PatientOrder;
use common\models\shop\Shop;
use services\patient\PatientOrderService;
use Yii;
use yii\base\Model;

/**
 * Class PatientOrderForm
 * @package api\modules\mini\forms\patient
 */
class PatientOrderForm extends Model
{
    /**
     * @var int $id ID
     * @var int $patient_id 患者ID
     * @var string $order_time 预约日期
     * @var int $treatment_project_id 项目ID
     * @var int $shop_id 门店ID
     * @var string $remark 备注
     */
    public $id;
    public $patient_id;
    public $order_time;
    public $treatment_project_id;
    public $shop_id;
    public $remark;

    /**
     * @var Patient $_patient
     * @var PatientOrder $_patientOrder
     * @var TreatmentProject $_treatmentProject
     * @var Shop $_shop
     */
    protected $_patient;
    protected $_patientOrder;
    protected $_treatmentProject;
    protected $_shop;


    public function rules()
    {
        return [
            // 参数验证
            [['patient_id', 'order_time', 'treatment_project_id', 'shop_id'], 'required', 'message' => '{attribute}不能为空', 'on' => ['create']],
            [['id', 'patient_id', 'order_time', 'treatment_project_id', 'shop_id'], 'required', 'message' => '{attribute}不能为空', 'on' => ['edit']],

            [['id'], 'checkId', 'skipOnEmpty' => false, 'on' => ['edit']],
            [['patient_id'], 'checkPatientId', 'skipOnEmpty' => false, 'on' => ['edit']],
            [['order_time'], 'checkOrderTime', 'skipOnEmpty' => false, 'on' => ['create']],
            [['treatment_project_id'], 'checkTreatmentProjectId', 'skipOnEmpty' => false, 'on' => ['create']],
            [['shop_id'], 'checkShopId', 'skipOnEmpty' => false, 'on' => ['create']],
            [['remark'], 'checkRemark', 'skipOnEmpty' => false, 'on' => ['create', 'edit']],
        ];
    }

    public function scenarios()
    {
        $scenarios = parent::scenarios();

        // 新增
        $scenarios['create'] = ['patient_id', 'order_time', 'treatment_project_id', 'shop_id', 'remark'];
        // 编辑
        $scenarios['edit'] = ['id', 'patient_id', 'order_time', 'treatment_project_id', 'shop_id', 'remark'];

        return $scenarios;
    }

    /**
     * @return array
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'order_time' => '预约时间',
            'treatment_project_id' => '项目',
            'shop_id' => '门店',
            'remark' => '备注',
        ];
    }

    /**
     * 检验ID
     * @param $attribute
     * @return void
     */
    public function checkId($attribute)
    {
        if ($this->hasErrors()) {
            return;
        }

        $patientOrder = $this->getPatientOrder();
        if (empty($patientOrder)) {
            $this->addError($attribute, '预约不存在');
            return;
        }
        if (PatientOrderService::isExpired($patientOrder->order_time)) {
            $this->addError($attribute, '预约日期小于当天无法修改');
            return;
        }
    }

    /**
     * 检验姓名
     * @param $attribute
     * @return void
     */
    public function checkPatientId($attribute)
    {
        if ($this->hasErrors()) {
            return;
        }

        $patient = $this->getPatient();
        if (empty($patient)) {
            $this->addError($attribute, '客户不存在');
            return;
        }
        $patientOrder = $this->getPatientOrder();
        if ($patientOrder->patient_id != $patient->id) {
            $this->addError($attribute, '客户异常，非当前账号所属');
            return;
        }
        if ($patient->user_id != Yii::$app->user->identity->member_id) {
            $this->addError($attribute, '客户异常，非当前账号所属');
            return;
        }
        if ($patient->status != Patient::STATUS_ENABLE) {
            $this->addError($attribute, '客户非正常状态');
            return;
        }
    }

    /**
     * 检验预约日期
     * @param $attribute
     * @return void
     */
    public function checkOrderTime($attribute)
    {
        if ($this->hasErrors()) {
            return;
        }
        if (empty($this->order_time)) {
            return;
        }
        $today = DateHelper::today();
        if (strtotime($this->order_time) < $today['start']) {
            $this->addError($attribute, '预约日期不能小于当天');
            return;
        }
    }

    /**
     * 检验项目
     * @param $attribute
     * @return void
     */
    public function checkTreatmentProjectId($attribute)
    {
        if ($this->hasErrors()) {
            return;
        }
        $treatmentProject = $this->getTreatmentProject();
        if (empty($treatmentProject)) {
            $this->addError($attribute, '项目不存在');
            return;
        }
        if ($treatmentProject->status != TreatmentProject::STATUS_ENABLE) {
            $this->addError($attribute, '项目状态异常');
            return;
        }
    }

    /**
     * 检验门店
     * @param $attribute
     * @return void
     */
    public function checkShopId($attribute)
    {
        if ($this->hasErrors()) {
            return;
        }
        $shop = $this->getShop();
        if (empty($shop)) {
            $this->addError($attribute, '门店不存在');
            return;
        }
    }

    /**
     * 检验折扣
     * @param $attribute
     * @return void
     */
    public function checkDiscountRate($attribute)
    {
        if ($this->hasErrors()) {
            return;
        }
        if (!is_numeric($this->discount_rate)) {
            $this->addError($attribute, '请输入正确折扣，单位：%');
            return;
        }
        if ($this->discount_rate < 60 || $this->discount_rate > 100) {
            $this->addError($attribute, '折扣超出范围【60~100之间】');
            return;
        }
    }

    /**
     * 检验备注
     * @param $attribute
     * @return void
     */
    public function checkRemark($attribute)
    {
        if ($this->hasErrors()) {
            return;
        }
        if (mb_strlen($this->remark) > 512) {
            $this->addError($attribute, '备注内容过长【512字以内】');
            return;
        }
    }

    public function getPatient(): ?Patient
    {
        if (is_null($this->_patient)) {
            $this->_patient =  Patient::findOne($this->patient_id);
        }
        return $this->_patient;
    }

    public function getPatientOrder(): ?PatientOrder
    {
        if (is_null($this->_patientOrder)) {
            $this->_patientOrder =  PatientOrder::findOne($this->id);
        }
        return $this->_patientOrder;
    }

    public function getTreatmentProject(): ?TreatmentProject
    {
        if (is_null($this->_treatmentProject)) {
            $this->_treatmentProject =  TreatmentProject::findOne($this->treatment_project_id);
        }
        return $this->_treatmentProject;
    }

    public function getShop(): ?Shop
    {
        if (is_null($this->_shop)) {
            $this->_shop =  Shop::findOne($this->shop_id);
        }
        return $this->_shop;
    }
}